package com.ihealthway.all.groupbuy.modules.front;

import com.ihealthway.all.groupbuy.services.*;
import com.ihealthway.all.task.ExecutorThreadPool;
import com.ihealthway.all.groupbuy.vo.UserInfo;
import com.ihealthway.all.commons.Constants;
import com.ihealthway.all.utils.Ajax;
import com.ihealthway.all.utils.AjaxReturn;
import com.ihealthway.all.groupbuy.vo.Goods;
import com.ihealthway.all.groupbuy.vo.OrderInfo;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * Front product page class
 *
 * @author 凡梦星尘(elkan1788@gmail.com)
 */
@At("/front/goods")
@IocBean
public class ShopGoodsModule {

    private static final Log logger = Logs.get();

    @Inject
    private PropertiesProxy conf;

    @Inject
    private ImageLibraryService imgLibService;

    @Inject
    private GoodsService goodsService;

    @Inject
    private OrderInfoService orderInfoService;

    @Inject
    private MPSettingService mpSettingService;

    @Inject
    private RewardInfoService rewardInfoService;

    @Inject
    private WinnerLogService winLogService;

    @At
    @Ok("beetl:front/shop_goods.jsp")
    public void home(@Param("..") NutMap nutMap, HttpServletRequest req) {
        logger.info("Product Index Info...");
        logger.info(nutMap);
        // search top 30 product
        UserInfo user = (UserInfo) req.getSession().getAttribute(Constants.WECHAT_LOGIN_SESSION);
        List<Goods> goodsList =  goodsService.getGoodsListIOnFront(user.getCompanyId(), null, nutMap.getString("gsName"));
        List<Goods> goodsAList = new ArrayList<>();
        List<Goods> goodsBList = new ArrayList<>();

        goodsList.forEach(gs -> {
            if (gs.getType().intValue() == 1) {
                goodsAList.add(gs);
            } else {
                goodsBList.add(gs);
            }
        });

        if (Strings.isNotBlank(nutMap.getString("gsName"))) {
            req.setAttribute("gsName", nutMap.getString("gsName"));
        }
        req.setAttribute("gsA", goodsAList);
        req.setAttribute("gsB", goodsBList);
    }

    @At
    @Ok("beetl:front/shop_goods_detail.jsp")
    public void detailInfo(@Param("..") NutMap nutMap, HttpServletRequest req) {
        /*NutMap jsSDKSet = new NutMap("domain", conf.get("server_domain"));
        MPSetting mpSet = mpSettingService.get();

        String shareUrl = new StringBuffer(req.getScheme()).append("://").append(conf.get("server_domain"))
                .append(req.getRequestURI()).append("?pid=").append(nutMap.getInt("pid")).toString();
        String nonceStr = Integer.toString(Utils.buildRandom(10));
        Long timestamp = System.currentTimeMillis() / 1000;
        String jsTicket = mpSet.getJsTicket();

        String signParam = new StringBuffer("jsapi_ticket=").append(jsTicket)
                .append("&noncestr=").append(nonceStr)
                .append("&timestamp=").append(timestamp)
                .append("&url=").append(shareUrl).toString();

        jsSDKSet.put("appId", mpSet.getAppId());
        jsSDKSet.put("url", shareUrl);
        jsSDKSet.put("nonce", nonceStr);
        jsSDKSet.put("timestamp", timestamp);
        try {
            String jsSign = SHA1.calculate(signParam);
            jsSDKSet.put("sign", jsSign);
            logger.debug(signParam);
        } catch (AesException e) {
            logger.error("Create JSSDK sign key fail!!!", e);
        }
*/
        // win lottery
        Goods goods = goodsService.getGoodsInfoOnFront(nutMap.getInt("pid"));
        /*Reward reward = new Reward();
        if (Strings.isNotBlank(goods.getShareDes())) {
            reward = rewardInfoService.winLottery();
            logger.infof("Win lottery rewards: %s", reward);
        }

        req.setAttribute("rwd", reward==null ? new Reward() : reward);*/

        req.setAttribute("imgs", imgLibService.getImagesOnFront(nutMap.getInt("pid")));
        req.setAttribute("goods", goods);
        req.setAttribute("actEt", goods.getEndTime().getTime());
        req.setAttribute("user", req.getSession().getAttribute(Constants.WECHAT_LOGIN_SESSION));
        /*req.setAttribute("jssdk", jsSDKSet);*/
    }

    /**
     * code means:
     * <ul>
     *     <li>200: success</li>
     *     <li>201: ordered</li>
     *     <li>202: limited</li>
     *     <li>500: system fail</li>
     * </ul>
     * @param goodsId   goods id
     * @param req   servlet request
     * @return  ajax return
     */
    @At
    @POST
    public AjaxReturn buildGoodsOrder(@Param("goodsId") Integer goodsId, HttpServletRequest req) {
        AjaxReturn ar = Ajax.ok();
        UserInfo userInfo = (UserInfo) req.getSession().getAttribute(Constants.WECHAT_LOGIN_SESSION);

        // 1. Check order list
        boolean ordered = orderInfoService.checkOrderList(goodsId, userInfo.getUserId());
        if (ordered) {
            ar.setOk(false);
            ar.setErrCode("201");
            return ar;
        }

        // 2. Check goods limit status
        boolean enough = goodsService.checkGoodsLimit(goodsId);
        if (enough) {
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setCompanyId(userInfo.getCompanyId());
            orderInfo.setUserId(userInfo.getUserId());
            orderInfo.setGoodsId(goodsId);
            orderInfo.setUserAgent(req.getHeader("user-agent"));
            logger.debugf("User Agent: %s", orderInfo.getUserAgent());
            String orderNo = orderInfoService.buildOrder(orderInfo);
            if (orderNo != null) {
                ExecutorThreadPool.execute(() -> {
                    goodsService.increaseGoodsSale(goodsId);
                });
                ar.setData(orderNo);
            } else {
                ar.setOk(false);
                ar.setErrCode("500");
            }
        } else {
            ar.setOk(false);
            ar.setErrCode("202");
        }


        return ar;
    }

    /*@At
    @Ok("beetl:front/scratch_card.jsp")
    public void enterLottery(@Param("rwdId") Integer rwdId, @Param("rwdImg") String rwdImg, HttpServletRequest req) {

        req.setAttribute("rwdId", rwdId);
        req.setAttribute("rwdImg", rwdImg);
    }

    @At
    @POST
    public AjaxReturn bookInWinLog(@Param("rwdId") Integer rwdId, @Param("gId") Integer gId, @Param("wUser") String wUser,
                                   @Param("wPhone") String wPhone, @Param("wArea") String wArea,
                                   @Param("wAddr") String wAddr, HttpServletRequest req) {
        AjaxReturn ar = Ajax.ok();
        UserInfo userInfo = (UserInfo) req.getSession().getAttribute(Constants.WECHAT_LOGIN_SESSION);
        WinnerLog wl = new WinnerLog();
        wl.setRewardId(rwdId);
        wl.setGoodsId(gId);
        wl.setUserId(userInfo.getUserId());
        wl.setWinnerPhone(wPhone);
        String[] areas = wArea.split(" ");
        wl.setWinnerProvince(areas[0]);
        wl.setWinnerCity(areas[1]);
        wl.setWinnerArea(areas[2]);
        wl.setWinnerAddress(wAddr);
        WinnerLog tmp = winLogService.addWinnerLog(wl);
        ar.setOk(tmp==null);
        return ar;
    }*/
}
